﻿#region NeoPatterns
// 
// NeoPatterns framework is released under LGPLv3 license.
// See http://www.opensource.org/licenses/lgpl-3.0.html for more details.
// 
// Please visit http://neopatterns.wikidot.com for more information about NeoPatterns
// 
// Copyright (c) Pascal Craponne 2008
// 
#endregion

using System;
using System.Collections.Generic;
using NeoPatterns.Core.Registry;

namespace NeoPatterns.Utility
{
    /// <summary>
    /// "Running" object definition.
    /// This class is an helper to ease writing of object definitions.
    /// </summary>
    public class ObjectDefinitionTransport
    {
        public IObjectRegistry ObjectRegistry { get; protected set; }

        public Type Type { get; protected set; }
        public string Name { get; protected set; }
        public IList<Ref> Advisors { get; protected set; }
        public bool Instance { get; protected set; }
        public Delegate Creator { get; protected set; }
        public Delegate Initializer { get; protected set; }

        public ObjectDefinitionTransport(IObjectRegistry objectRegistry)
        {
            ObjectRegistry = objectRegistry;
        }

        public void UnderName(string name)
        {
            Name = name;
            RegisterDefinition();
        }

        public void UnderNoName()
        {
            RegisterDefinition();
        }

        protected virtual void RegisterDefinition()
        {
            ObjectRegistry.RegisterDefinition(Name, Type, Advisors, Instance, Creator, Initializer);
        }
    }

    /// <summary>
    /// Running object definition, generic version
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObjectDefinitionTransport<T> : ObjectDefinitionTransport
    {
        public ObjectDefinitionTransport(IObjectRegistry objectRegistry)
            : base(objectRegistry)
        {
            Type = typeof(T);
        }

        public ObjectDefinitionTransport<T> WithCreator(Func<IObjectRegistry, T> creator)
        {
            Creator = creator;
            return this;
        }

        public ObjectDefinitionTransport<T> WithInitializer(Action<T, IObjectRegistry> initializer)
        {
            Initializer = initializer;
            return this;
        }

        public ObjectDefinitionTransport<T> WithAdvisor(Ref advisor)
        {
            if (Advisors == null)
                Advisors = new List<Ref>();
            Advisors.Add(advisor);
            return this;
        }

        public ObjectDefinitionTransport<T> AsInstance()
        {
            Instance = true;
            return this;
        }
    }
}